#include "ch32v30x.h"

/************ 全局变量 ************/
uint32_t SystemCoreClock = 144000000;

/************ 中断处理函数 ************/

__attribute__((interrupt("WCH-Interrupt-fast")))
void HardFault_Handler(void){
    while(1);
}

__attribute__((interrupt("WCH-Interrupt-fast")))
void NMI_Handler(void){
    
}

/************ 系统时钟配置 ************/
void Sys_setClock(void){
    /* 启用HSE */
    __IO uint32_t  StartUpCounter = 0, HSEStatus = 0;
    RCC->CTLR |= ((uint32_t)RCC_HSEON);
    do{
        HSEStatus = RCC->CTLR & RCC_HSERDY;
        StartUpCounter++;
    }while ( (HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT) );
    if ( (RCC->CTLR & RCC_HSERDY) != RESET ){
        HSEStatus = (uint32_t)0x01;
    }else{
        HSEStatus = (uint32_t)0x00;
    }

    if ( HSEStatus == (uint32_t)0x01 ){
        RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
        RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
        RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
        RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
        RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
        while ( (RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04 );
    }else{
        /* HSE启动失败的处理 */
        return;
    }
    /* 配置时钟至144MHz */
    RCC->CTLR |= ((uint32_t)RCC_HSEON);
    do{
        HSEStatus = RCC->CTLR & RCC_HSERDY;
        StartUpCounter++;
    }while ( (HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ( (RCC->CTLR & RCC_HSERDY) != RESET){
        HSEStatus = (uint32_t)0x01;
    }else{
        HSEStatus = (uint32_t)0x00;
    }

    if ( HSEStatus == (uint32_t)0x01 ){
        RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
        RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
        RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
        RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
        RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN);
        /* 使能锁相环 */
        RCC->CTLR |= RCC_PLLON;
        while ( (RCC->CTLR & RCC_PLLRDY) == 0 );
        RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
        RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
        while ( (RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08 );
    }else{
        /* 外部时钟错误处理 */
        return;
    }
    SystemCoreClock = 144000000;
}

/************ 系统延时服务(SysTick) ************/
#ifndef USE_RTOS

static volatile uint8_t p_us = 0;
static volatile uint16_t p_ms = 0;

void Sys_delayInit(void){
    p_us = SystemCoreClock / ( 8 * 1000 * 1000 );
    p_ms = (uint16_t)p_us * 1000;
}

void Sys_delayUs(uint32_t nus){
    uint32_t i;
    SysTick->SR &= ~(1 << 0);
    i = (uint32_t)nus * p_us;
    SysTick->CMP = i;
    SysTick->CTLR |= (1 << 4);
    SysTick->CTLR |= (1 << 5) | (1 << 0);
    while ( (SysTick->SR & (1 << 0)) != (1 << 0) );
    SysTick->CTLR &= ~(1 << 0);
}

void Sys_delayMs(uint32_t nms){
    uint32_t i;
    SysTick->SR &= ~(1 << 0);
    i = (uint32_t)nms * p_ms;
    SysTick->CMP = i;
    SysTick->CTLR |= (1 << 4);
    SysTick->CTLR |= (1 << 5) | (1 << 0);
    while( (SysTick->SR & (1 << 0)) != (1 << 0) );
    SysTick->CTLR &= ~(1 << 0);
}

#endif

/************ 系统复位初始化 ************/

void SystemInit(void){
    RCC->CTLR |= (uint32_t)0x00000001;
    RCC->CFGR0 &= (uint32_t)0xf8ff0000;
    RCC->CFGR0 &= (uint32_t)0xf0ff0000;
    RCC->CTLR &= (uint32_t)0xfef6ffff;
    RCC->CTLR &= (uint32_t)0xfffbffff;
    RCC->CFGR0 &= (uint32_t)0xff80ffff;
    RCC->CTLR &= (uint32_t)0xebffffff;
    RCC->INTR = 0x00ff0000;
    RCC->CFGR2 = 0x00000000;
    RCC->INTR = 0x009f0000;
    Sys_setClock();
    // Sys_delayInit();
}


